package com.hainiu.cat.web.template;

import com.google.common.collect.Lists;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

/**
 * create by biji.zhao on 2021/6/29
 */
public class templateTest {

    @Data
    static class Animal {
        private Integer id;
    }

    public static <T> T createInstance(Class<T> clazz) throws InstantiationException, IllegalAccessException{
        return clazz.newInstance();
    }


    @Data
    static class Dog extends Animal {
        private String name;
    }

    interface MultiLimitInterfaceA{
        String nameA = "a";
        String soutOne(String name);
    }

    interface MultiLimitInterfaceB{
        String nameB = "B";
        String soutOne(String name);
    }

    static class MultiLimit implements MultiLimitInterfaceA, MultiLimitInterfaceB {
        private String name;

        @Override
        public String soutOne(String name) {
            return nameA + name + nameB;
        }
    }

    public static <T extends MultiLimitInterfaceA & MultiLimitInterfaceB> String test(T t, List<? super MultiLimit> mList) {
        return t.soutOne("海牛" + mList.size());
    }

    static int countLegs(List<? extends Animal> animals) {
        int retVal = 0;
        for (Animal animal : animals) {
            retVal += animal.getId();
        }
        return retVal;
    }

    static int countLegs1(List<Animal> animals) {
        int retVal = 0;
        for (Animal animal : animals) {
            retVal += animal.getId();
        }
        return retVal;
    }

    public static void main(String[] args) {
//        List<Dog> dogs = new ArrayList<>();
//        // 不会报错
//        countLegs(dogs);
//        // 报错
////        countLegs1(dogs);
//
//        Animal animal = new Animal();
//        animal.setId(1);
//
//        Dog dog = new Dog();
//        dog.setName("dog");
//
//        ArrayList<Animal> animals = Lists.newArrayList(animal);
//        ArrayList<Dog> dogs1 = Lists.newArrayList(dog);
//
//        testSuperTemplate(animals, dogs1);
//
//        animals.forEach(e -> System.out.println(e));

//        MultiLimit multiLimit = new MultiLimit();
//        multiLimit.name = "21w21";
//        System.out.println(test(multiLimit, Lists.newArrayList((MultiLimitInterfaceB) name -> "海牛大大")));

        try {
            MultiLimit instance = createInstance(MultiLimit.class);
            MultiLimitInterfaceA instance1 = createInstance(MultiLimitInterfaceA.class);
            System.out.println(instance.name);
            System.out.println(instance1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private static <T> void testSuperTemplate(List<? super T> dst, List<T> src){
        dst.addAll(src);
    }

    /**
     * T 是一个 确定的 类型，通常用于泛型类和泛型方法的定义
     * ？是一个 不确定 的类型，通常用于泛型方法的调用代码和形参，不能用于定义类和泛型方法
     */

    // 通过 T 来 确保 泛型参数的一致性
    public <T extends Number> void testT(List<T> dest, List<T> src){

    }

    // 通配符是 不确定的，所以这个方法不能保证两个 List 具有相同的元素类型
    public void test(List<? extends Number> dest, List<? extends Number> src){

    }
}
